// 引入LVGL图形库头文件
#include "lvgl/lvgl.h"
// 引入LVGL演示示例
#include "lvgl/demos/lv_demos.h"
// 引入Linux framebuffer显示驱动
#include "lv_drivers/display/fbdev.h"
// 引入Linux输入事件驱动
#include "lv_drivers/indev/evdev.h"

// 引入Unix标准库
#include <unistd.h>
// 引入POSIX线程库
#include <pthread.h>
// 引入时间处理库
#include <time.h>
// 引入系统时间库
#include <sys/time.h>
// 引入信号处理库
#include <signal.h>
// 引入标准库
#include <stdlib.h>

// 引入标准输入输出
#include <stdio.h>
// 引入中文字体文件
#include "test/lv_font_source_han_sans_bold.h"
// 引入界面显示模块
#include "test/interface_display.h"
// 引入网络通信模块
#include "test/parking_network.h"
// 引入硬件控制模块
#include "test/parking_hardware.h"
// 引入命令处理模块
#include "test/parking_commands.h"

// 定义显示缓冲区大小（480行，每行1024像素）
#define DISP_BUF_SIZE (480 * 1024)

// 信号处理函数 - 处理程序退出信号
void signal_handler(int sig)
{
    // 打印接收到的信号编号
    printf("Received signal %d, shutting down...\n", sig);
    // 停止网络客户端
    network_stop_client();
    // 关闭硬件设备
    close_hardware_devices();
    // 退出程序
    exit(0);
}

// 系统初始化函数
void initialize_system()
{
    // 设置随机数种子为当前时间
    srand(time(NULL));

    // // 打印内存对齐检查信息
    // printf("=== Memory Alignment Check ===\n");
    // // 输出停车场数据结构体的大小
    // printf("DEBUG: sizeof(parking_data_t) = %zu bytes\n", sizeof(parking_data_t));
    // // 输出total_spaces字段在结构体中的偏移量
    // printf("DEBUG: offsetof(total_spaces) = %zu\n", offsetof(parking_data_t, total_spaces));
    // // 输出available_spaces字段在结构体中的偏移量
    // printf("DEBUG: offsetof(available_spaces) = %zu\n", offsetof(parking_data_t, available_spaces));
    // // 输出timestamp字段在结构体中的偏移量
    // printf("DEBUG: offsetof(timestamp) = %zu\n", offsetof(parking_data_t, timestamp));
    // // 输出common_feedback字段在结构体中的偏移量
    // printf("DEBUG: offsetof(common_feedback) = %zu\n", offsetof(parking_data_t, common_feedback));
    // // 输出hour_20_count字段在结构体中的偏移量
    // printf("DEBUG: offsetof(hour_20_count) = %zu\n", offsetof(parking_data_t, hour_20_count));

    // 打印系统初始化完成信息
    printf("System initialized\n");
}

// 主函数 - 程序入口点
int main(void)
{
    // 系统初始化
    initialize_system();

    // 初始化默认数据 - 在UI创建之前执行！吗
    initialize_default_data();

    // 设置信号处理 - 注册SIGINT信号（Ctrl+C）的处理函数
    signal(SIGINT, signal_handler);
    // 设置信号处理 - 注册SIGTERM信号（终止信号）的处理函数
    signal(SIGTERM, signal_handler);

    // 打印系统启动信息
    printf("Parking Management System Starting...\n");

    // 初始化硬件设备 - 蜂鸣器
    if(init_buzzer_device() != 0) {
        printf("Warning: Buzzer device initialization failed\n");
    }

    // 初始化硬件设备 - LED
    if(init_led_device() != 0) {
        printf("Warning: LED device initialization failed\n");
    }

    // 调试信息：LVGL初始化前
    //printf("Before lv_init\n");

    /* LVGL初始化 - 初始化LittleVGL图形库 */
    lv_init();

    // 调试信息：LVGL初始化后，framebuffer初始化前
    printf("After lv_init, before fbdev_init\n");

    /* 输出设备初始化及注册 - 初始化framebuffer设备 */
    fbdev_init();

    // 调试信息：framebuffer初始化后，显示缓冲区设置前
    //printf("After fbdev_init, before setting display buffer\n");

    /* 为LittleVGL绘制屏幕内容分配一个小缓冲区 */
    static lv_color_t buf[DISP_BUF_SIZE];
    /* 初始化缓冲区的描述符 */
    static lv_disp_draw_buf_t disp_buf;
    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);

    // 调试信息：显示缓冲区设置后，显示驱动注册前
    //printf("After setting display buffer, before display driver\n");

    /* 初始化并注册显示驱动 */
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);          // 初始化显示驱动结构体
    disp_drv.draw_buf = &disp_buf;        // 设置绘制缓冲区
    disp_drv.flush_cb = fbdev_flush;      // 设置刷新回调函数
    disp_drv.hor_res  = 800;              // 设置水平分辨率
    disp_drv.ver_res  = 480;              // 设置垂直分辨率
    lv_disp_drv_register(&disp_drv);      // 注册显示驱动

    // 调试信息：显示驱动注册后，输入设备初始化前
    //printf("After display driver, before input device\n");

    // 输入设备初始化及注册
    evdev_init();                         // 初始化输入事件设备
    static lv_indev_drv_t indev_drv_1;
    lv_indev_drv_init(&indev_drv_1);      /* 基本初始化 */
    indev_drv_1.type = LV_INDEV_TYPE_POINTER;  // 设置输入设备类型为指针（触摸屏/鼠标）
    /* 这个函数将被库定期调用以获取鼠标位置和状态 */
    indev_drv_1.read_cb = evdev_read;     // 设置读取回调函数
    lv_indev_drv_register(&indev_drv_1);  // 注册输入设备驱动

    // 调试信息：输入设备初始化后，创建仪表盘前
    //printf("After input device, before create_parking_dashboard\n");

    // 创建UI界面 - 完全保持原有的界面
    create_parking_dashboard();

    // 调试信息：仪表盘创建后，启动TCP客户端前
    //printf("After create_parking_dashboard, before start_tcp_client\n");

    // 启动TCP客户端线程 - 连接到服务器并开始数据通信
    network_start_client();

    // 打印系统启动成功信息
    printf("System started successfully\n");
    //printf("UI is running and data is being sent to cloud\n");

    /* 事务处理及告知LVGL节拍数 - 主事件循环 */
    while(1) {
        lv_timer_handler(); // LVGL事务处理 - 处理所有定时器和事件
        lv_tick_inc(5);     // LVGL节拍累计 - 增加5毫秒的节拍
        usleep(5000);       // 休眠5毫秒（5000微秒）
    }

    // 主循环不会退出，这里返回0仅为了语法正确
    return 0;
}

/* 用户节拍获取函数 - 为LVGL提供时间基准 */
uint32_t custom_tick_get(void)
{
    // 静态变量记录起始时间（毫秒）
    static uint64_t start_ms = 0;
    // 如果起始时间未初始化，进行初始化
    if(start_ms == 0) {
        struct timeval tv_start;
        gettimeofday(&tv_start, NULL);  // 获取当前时间
        // 计算起始时间（毫秒）：秒*1000 + 微秒/1000
        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
    }

    // 获取当前时间
    struct timeval tv_now;
    gettimeofday(&tv_now, NULL);
    uint64_t now_ms;
    // 计算当前时间（毫秒）
    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

    // 返回从程序开始到现在的毫秒数
    uint32_t time_ms = now_ms - start_ms;
    return time_ms;
}